package org.softmed.rest.server.xstream;

import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.softmed.persistence.PersistenceManager;
import org.softmed.reflection.utils.FieldInfo;
import org.softmed.reflection.utils.ReflectionUtil;
import org.softmed.rest.config.Application;
import org.softmed.rest.generation.ScafoldFacade;
import org.softmed.rest.generation.fields.FieldNameList;
import org.softmed.rest.generation.fields.GenerationConfig;
import org.softmed.rest.generation.scafold.AppConfig;
import org.softmed.rest.generation.uri.URIBuilder;

import com.thoughtworks.xstream.XStream;

public class CustomDefaultXMLUnmarshaller {

	// ReflectionUtil util = new ReflectionUtil();
	// List<Class> compiledClasses = new ArrayList<Class>();
	private Class type;
	private XStream streamer;
	private GenerationConfig genCfg;
	private Collection<FieldInfo> genFields;
	UnmarshallConfigurator config = new UnmarshallConfigurator();

	public CustomDefaultXMLUnmarshaller(PersistenceManager odbUtil, Class type,
			Application app) throws Throwable {
		this.type = type;

		// compiledClasses.clear();

		streamer = XStreamManager.getXStream();
//		streamer.alias("wtf", type);
		streamer.registerConverter(new BigIntegerConverter());
		streamer.registerConverter(new BigDecimalConverter());
		streamer.registerConverter(new DateConverter());
		// streamer.registerConverter(new TimestampConverter());

		AppConfig genApp = ScafoldFacade.getApp(app);
		URIBuilder uriBuilder = genApp.getUriBuilder();
		genCfg = genApp.getGenerationConfig();

		config.setupXMLStreamer(odbUtil, type, streamer, genCfg);
//		genFields = odbUtil.getGeneratedFields(type);

		// Object obj = streamer.fromXML("<wtf />");
		// System.out.println(obj);
	}

	public Object fromXML(PersistenceManager odbUtil,String xml) throws Throwable {

		// streamer = XStreamManager.getXStream();
		// streamer.alias("wtf", type);
		// streamer.omitField(type, "metaClass");
		// Object obje = streamer.fromXML(xml);

		Object obj = null;
		try {

			ByteArrayInputStream bais = new ByteArrayInputStream(xml
					.getBytes(XStreamManager.CHAR_SET));
			// InputStreamReader is = new InputStreamReader(bais,
			// XStreamManager.CHAR_SET);

			// streamer.
			// streamer = XStreamManager.getXStream();
			// streamer.alias("wtf", type);
			// streamer.omitField(type, "metaClass");
			obj = streamer.fromXML(bais);

			genFields = null;
			genFields = odbUtil.getGeneratedFields(obj.getClass());
			// clean up any generated fields that might have "passed" through
			// XML unmarshalling
			if (genFields != null)
				for (FieldInfo fieldInfo : genFields) {
					fieldInfo.getSetter().invoke(obj, new Object[] { null });
				}

		} catch (Throwable t) {
			return null;
		}

		return obj;

	}

}
